/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.alevsk.antwars;

import java.awt.Point;
import java.io.*;
import java.net.Socket;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;

/**
 *
 * @author
 */
public class ServerDispatcher implements Runnable {

    int numCli;
    int mov;
    Socket output;
    Semaphore sem;
    socketshormigas serverdata;
    Player jugador;

    ServerDispatcher(int n, Semaphore s, Socket o, socketshormigas d) {
        output = o;
        serverdata = d;
        numCli = n;
        sem = s;
        mov = 0;
        Point hormiguero = d.mapa.getHormiguero(numCli + 1);
        jugador = new Player(numCli, hormiguero);

        agregar_ants2map(jugador.Player_ants_warriors, hormiguero);
        agregar_ants2map(jugador.Player_ants_explorers, hormiguero);
        agregar_ants2map(jugador.Player_ants_workers, hormiguero);

        d.Player_list.add(jugador);

    }

    void agregar_ants2map(LinkedList hormigas, Point place) {
        for (int i = 0; i < hormigas.size(); i++) {
            Ant nueva = (Ant) hormigas.get(i);
            serverdata.mapa.cells[place.x][place.y].addAnt(nueva);
            
            /*
             * int idExploradora = jugador.Player_ants_workers.get(i).id; int
             * idRecolectora = jugador.Player_ants_explorers.get(i).id;
             */
        }

    }

    public void run() {
        //condicion para esperar a que se conecten todos los clientes
        //comentada por propositos de testing
        while (serverdata.numCli != serverdata.maxCli) {
            System.out.print("");
        }
        try {
            System.out.println("Sirvo al cliente " + numCli);
            OutputStream aux = output.getOutputStream();
            ObjectOutputStream os = new ObjectOutputStream(aux);
            InputStream aux2 = output.getInputStream();
            ObjectInputStream is = new ObjectInputStream(aux2);
            // DataOutputStream enteros = new DataOutputStream(aux);//enviar enteros
            //os.writeObject("Esperando a otros clientes para empezar partida");
            // enteros.writeInt(numCli);//enviar enteros
            while (serverdata.numCli != serverdata.maxCli) {
                System.out.print("");
            }//esperamos
            //os.writeObject("Esperando a otros clientes para empezar partida");
            //os.writeObject(testing());
            //enviariddeturno
            JFrame aplicacion =new JFrame("Jugador "+numCli);
            Panel panel = new Panel(600/serverdata.mapa.h+2,jugador,serverdata.mapa);
            aplicacion.add(panel);
            aplicacion.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            aplicacion.setSize(600+50, (600/serverdata.mapa.h)*serverdata.mapa.w);
            aplicacion.setVisible(true);
            os.writeObject(new Inicial(serverdata.mapa.h, serverdata.mapa.w, Constantes.max_workers, Constantes.max_explorers, Constantes.max_warriors));
            System.out.println("Mande el estado inicial");
            //ciclo while food!=0 and obreras!=0

            while (serverdata.remfood != 0) {//hace falta manipular esta variable y ponerle un valor al cargar el mapa y verificar los puntos de comida
                //validarturno()---semaforo!
                if (numCli == serverdata.turno) {
                    try {
                        sem.acquire();//semaforo que esta solo como medida de seguridad
                    } catch (InterruptedException ex) {
                        Logger.getLogger(ServerDispatcher.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    /*switch (mov) {
                        case 0:
                        * 
                        */
                            os.writeObject(new AntsView(jugador, serverdata.mapa));
                            System.out.println("Mande el AntsView");
                            //se mandan las perspectivas de las hormigas
                            //las clases pertinentes deben ser agregadas
                            /*mov++;
                            break;
                        case 1://recive movimientos de jugador
                        * 
                        */
                            MoveList movimientos;
                            movimientos = (MoveList) is.readObject();
                            System.out.println("Lei los movimientos");
                            ListIterator itr = movimientos.moves.listIterator();
                            while (itr.hasNext()) {
                                Move movimiento = (Move) itr.next();
                                Ant hormiga = (Ant) jugador.Player_ants[movimiento.id_H];
                                if(validar_movimiento(movimiento, serverdata.mapa)){
                                    serverdata.mapa.cells[hormiga.place.x][hormiga.place.y].removeAnt(hormiga);
                                    hormiga.move(movimiento.move);
                                    serverdata.mapa.cells[hormiga.place.x][hormiga.place.y].addAnt(hormiga);
                                    if(serverdata.mapa.cells[hormiga.place.x][hormiga.place.y].comida!=0){
                                        int posee = hormiga.food;
                                        hormiga.take(serverdata.mapa.cells[hormiga.place.x][hormiga.place.y].comida);
                                        int posee_ahora = hormiga.food;
                                        int tomado = posee_ahora - posee;
                                        //;
                                        serverdata.mapa.cells[hormiga.place.x][hormiga.place.y].removeFood(tomado);
                                    }
                                    if(hormiga.place == serverdata.mapa.getHormiguero(jugador.id_player)){
                                        if(hormiga.comida_cargada() > 0){
                                            int cuanto = hormiga.comida_cargada();
                                            hormiga.score();
                                            //Aquí se debería de depositar puntos al usuario??
                                            serverdata.mapa.food=serverdata.mapa.getTotalFood()-cuanto;
                                        }
                                        
                                    }
                                }
                                //
                                //
                                
                                
                                //System.out.println(movimiento.id_H + " " + hormiga.place.x + " " + hormiga.place.y);
                            }
                            panel.repaint();
                            //rellenar aqui los movimientos necesarios para recibir
                            //el objeto del cliente
                            //aun no se agregan las estructuras para el manejo
                            //de los datos en esta clase
                                /*
                             * if(numCli == (serverdata.maxCli-1))//el ultimo
                             * cliente en ser atendido le pide al server que
                             * resuelva movimientos serverdata.resolver();//se
                             * actualiza comida, batallas, etc. No implementada
                             * aun //pueden pasarle como argumento lo que te da
                             * el cliente
                             */
                            /*mov = 0;
                            break;
                    }
                    * 
                    */
                    serverdata.turno = (serverdata.turno + 1) % serverdata.maxCli; //cambiamos de turno
                    sem.release();//semaforo solo por cuestiones de seguridad
                }
                System.out.print("");
            }

            /*
             * while(serverdata.remfood != 0){//hace falta manipular esta
             * variable y ponerle un valor al cargar el mapa y verificar los
             * puntos de comida //validarturno()---semaforo! if(numCli ==
             * serverdata.turno){ sem.acquire();//semaforo que esta solo como
             * medida de seguridad switch(mov){ case 0: //se mandan las
             * perspectivas de las hormigas //las clases pertinentes deben ser
             * agregadas mov++; break; case 1://recive movimientos de jugador
             * os.writeObject("Preparado para recibir datos"); //rellenar aqui
             * los movimientos necesarios para recibir //el objeto del cliente
             * //aun no se agregan las estructuras para el manejo //de los datos
             * en esta clase if(numCli == (serverdata.maxCli-1))//el ultimo
             * cliente en ser atendido le pide al server que resuelva
             * movimientos serverdata.resolver();//se actualiza comida,
             * batallas, etc. No implementada aun //pueden pasarle como
             * argumento lo que te da el cliente
             *
             * mov = 0; break; } serverdata.turno =
             * (serverdata.turno+1)%serverdata.maxCli; //cambiamos de turno
             * sem.release();//semaforo solo por cuestiones de seguridad } }
             */

            output.close();
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ServerDispatcher.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }/*
         * catch(InterruptedException e){ System.out.println(e.getMessage());
         * }/*catch(ClassNotFoundException e){
         * System.out.println(e.getMessage()); }
         */ //catch en caso de que se necesite en un futuro
    }

    /*
     * public AntsView testing() { AntsView lala = new AntsView(); Perspective
     * burro = new Perspective(); Celda link = new Celda(); Tile lolo = new
     * Tile(link); burro.addTile(lolo); lala.addPerspective(burro); return lala;
    }
     */

    private boolean validar_movimiento(Move movimiento, Mapa mapa) {
        Ant dummy = new Ant (jugador.Player_ants[movimiento.id_H].id, 
                jugador.Player_ants[movimiento.id_H].type, 
                jugador.Player_ants[movimiento.id_H].place.x, 
                jugador.Player_ants[movimiento.id_H].place.y);
        dummy.move(movimiento.move);
        if(serverdata.mapa.cells[dummy.place.x][dummy.place.y].tipo==Constantes.obstaculo){
            return false;
        }
        return true;
        
    }
}
